if (!this.Proxy) {
    (function (window) {
        var dfGetter = function (target, property, receiver) {
            return target[property];
        };
        var dfSetter = function (target, property, value, receiver) {
            target[property] = value;
        };
        var afterRevoke = function () {
            throw new Error("illegal operation attempted on a revoked proxy");
        };
        window.Proxy = function (target, handler) {
            var that = this;
            if (!handler.get) {
                handler.get = dfGetter;
            }
            if (!handler.set) {
                handler.set = dfSetter;
            }
            for (var key in target) {
                Object.defineProperty(that, key, {
                    enumerable: true,
                    set: function (val) {
                        handler.set(target, key, val, that);
                    },
                    get: function () {
                        return handler.get(target, key, that);
                    }
                });
            }
        };
        window.Proxy.revocable = function (target, handler) {
            var r = {};
            r.proxy = new Proxy(target, handler);
            r.revoke = function () {
                handler.get = handler.set = afterRevoke;
            };
            return r;
        };
    })(this);
}

var person = {
    name: "张三"
};
var proxy = new Proxy(person, {
    set: function (target, property, value) {
        if (property in target) {
            console.log("set " + property + ":" + value);
        } else {
            throw new Error("Property \"" + property + "\" does not exist.");
        }
    }
});
proxy.name = "李四";
